package cn.lysj.framework.common.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.lysj.framework.base.BaseController;
import cn.lysj.framework.common.CommonConstant;
import cn.lysj.framework.common.OrderPayConstant;
import cn.lysj.framework.common.annotation.SystemLog;
import cn.lysj.framework.common.domain.Role;
import cn.lysj.framework.common.domain.User;
import cn.lysj.framework.common.domain.UserRole;
import cn.lysj.framework.common.dto.MerchantInfoDto;
import cn.lysj.framework.common.service.RoleService;
import cn.lysj.framework.common.service.UserRoleService;
import cn.lysj.framework.common.service.UserService;
import cn.lysj.framework.common.utils.pagination.PageVo;
import cn.lysj.framework.common.utils.web.ParamUtil;
import cn.lysj.framework.common.utils.web.Resp;
import cn.lysj.framework.common.validate.Message;
import cn.lysj.framework.common.validate.annotation.Pattern;
import cn.lysj.framework.common.validate.annotation.Validator;
import cn.lysj.framework.common.validate.entity.Medusa;
import cn.lysj.framework.config.domain.Config;
import cn.lysj.framework.config.repository.ConfigRepository;
import cn.lysj.framework.order.dto.AjaxResp;
import cn.lysj.framework.store.domain.Store;
import cn.lysj.framework.store.repository.StoreRepository;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author zk
 * @description 用户表控制层
 * @create 2018-07-25 15:02:19
 **/
@Slf4j
@RestController
@Api(description = "用户表管理接口")
@RequestMapping("/admin/user")
public class UserController extends BaseController<User> {

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private StoreRepository storeRepository;
    @Resource
    private ConfigRepository configRepository;

    @Override
    public UserService getService() {
        return userService;
    }

    /**
     * @author zk
     * @date 2018-08-13 21:03
     * @Description 查询用户
     */
    @SystemLog(description = "查询用户")
    @Override
    @ApiOperation(value = "用户列表+查询")
    public Resp list(User entity, PageVo pageVo) {
        entity.setDelFlag(null);
        Page<User> page = getService().list(entity, pageVo);
        for (User user : page.getContent()) {
            user.setRoles(userRoleService.findUserRoleByUserId(user.getId()));
        }
        return new Resp(page);
    }

    /**
     * @author zk
     * @date 2018-08-13 20:20
     * @Description 添加用户
     */
    @PostMapping("/save_user")
    @ApiOperation(value = "添加用户")
    public Resp save(@Validator User entity, String[] roleIds) {
        if (ParamUtil.isBlank(entity.getUsername())) {
            return new Resp(Resp.PARAM_ERROR, "用户名不能为空");
        }
        User userQuery = userService.findByUsername(entity.getUsername());
        if (userQuery != null) {
            return new Resp(Resp.PARAM_ERROR, "用户名已存在");
        }
        entity.setPassword(new BCryptPasswordEncoder().encode(entity.getPassword()));
        Store store = new Store();
        store.setSupporyPayWay(3); //共同支持
        store = storeRepository.save(store);
        entity.setStoreId(store.getId());
        entity = userService.save(entity);
        //初始化store
        store.setUserId(entity.getId());
        store.setAdvanceProvideTime(0);
        store.setIntegralRatio(BigDecimal.ZERO);
        store.setBusinessTime("08:00-18:00");
        store.setBusinessType(2);
        store.setIsDoBusiness(true);
        storeRepository.save(store);
        //初始化门店的餐盒,餐具费用
        Config conifg = new Config();
        conifg.setStoreId(store.getId());
        conifg.setBoMoney(new BigDecimal("0.01")); //餐盒费
        conifg.setCutleryMoney(new BigDecimal("0.01"));
        configRepository.save(conifg);
        if (!ParamUtil.isBlank(roleIds)) {
            for (String s : roleIds) {
                if (!roleService.countRoleId(s)) {
                    return new Resp(Resp.PARAM_ERROR, "角色信息有误");
                }
                UserRole ur = new UserRole();
                ur.setRoleId(s);
                ur.setUserId(entity.getId());
                userRoleService.save(ur);
            }
        } else {
            List<Role> roles = roleService.findByDefaultRole(true);
            if (!ParamUtil.isBlank(roles)) {
                for (Role role : roles) {
                    UserRole ur = new UserRole();
                    ur.setRoleId(role.getId());
                    ur.setUserId(entity.getId());
                    userRoleService.save(ur);
                }
            }
        }
        //若用户添加阿里配置信息
        if (!ParamUtil.isBlank(entity.getAliAppId())) {
            MerchantInfoDto merchantInfoDto = new MerchantInfoDto();
            BeanUtils.copyProperties(entity, merchantInfoDto);
            RestTemplate restTemplate = new RestTemplate();
            AjaxResp resp = restTemplate.postForObject(OrderPayConstant.EDIT_MERCHANT_INFO, merchantInfoDto, AjaxResp.class);
            if (resp.getStatus().equals(AjaxResp.Status.SUCCESS)) {
                entity.setMerchantId(resp.getObj().toString());
                userService.save(entity);
            }
        }
        return new Resp("添加成功");
    }

    /**
     * @author zk
     * @date 2018-08-13 21:08
     * @Description 修改用户
     */
    @PostMapping("/update_user")
    @ApiOperation(value = "修改用户")
    public Resp update(User entity, String[] roleIds) {
        if (ParamUtil.isBlank(entity.getId())) {
            return new Resp(Resp.PARAM_ERROR, "参数错误，请重试");
        }
        User user = userService.findOne(entity.getId());
        if (user == null) {
            return new Resp(Resp.PARAM_ERROR, "查无此用户");
        }
        //获取Hutool拷贝实例
        CopyOptions copyOptions = CopyOptions.create();
        //忽略为null值得属性
        copyOptions.setIgnoreNullValue(true);
        //进行属性拷贝
        BeanUtil.copyProperties(entity, user, copyOptions);
        //对实体类中的@validation注解进行校验
        Medusa medusa = Message.getMsg(user, Message.getMap("password", Pattern.class));
        if (!medusa.isFlag()) {
            return new Resp(Resp.PARAM_ERROR, medusa.getMessage());
        }

        userRoleService.deleteByUserId(user.getId());
        for (String s : roleIds) {
            if (!roleService.countRoleId(s)) {
                return new Resp(Resp.PARAM_ERROR, "角色信息有误");
            }
            UserRole ur = new UserRole();
            ur.setRoleId(s);
            ur.setUserId(entity.getId());
            userRoleService.save(ur);
        }
        //若用户添加阿里或者微信支付配置信息
        if (!ParamUtil.isBlank(entity.getAliAppId())) {
            MerchantInfoDto merchantInfoDto = new MerchantInfoDto();
            if (!ParamUtil.isBlank(user.getMerchantId())) {
                entity.setMerchantId(user.getMerchantId());
            }
            BeanUtils.copyProperties(entity, merchantInfoDto);
            RestTemplate restTemplate = new RestTemplate();
            AjaxResp resp = restTemplate.postForObject(OrderPayConstant.EDIT_MERCHANT_INFO, merchantInfoDto, AjaxResp.class);
            if (resp.getStatus().equals(AjaxResp.Status.SUCCESS)) {
                user.setMerchantId(resp.getObj().toString());
                userService.save(user);
            }
        }
        return new Resp("修改成功");

    }

    /**
     * @author zk
     * @date 2018-08-13 20:41
     * @Description 修改密码
     */
    @PostMapping("/modify_password")
    @ApiOperation(value = "修改密码")
    @SystemLog(description = "修改密码")
    public Resp modifyPassword(String id, String password, String newPassword) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp(Resp.PARAM_ERROR, "查无此用户");
        }
        if (user.getDelFlag().equals(CommonConstant.DEL_FLAG)) {
            return new Resp(Resp.PARAM_ERROR, "该用户已被禁用");
        }
        if (!new BCryptPasswordEncoder().matches(password, user.getPassword())) {
            return new Resp(Resp.PARAM_ERROR, "旧密码不正确");
        }
        if (!newPassword.matches("/^[a-zA-Z0-9_-]{6,20}$/")) {
            return new Resp(Resp.PARAM_ERROR, "密码应为英文、数字、下划线组成的6-20位字符");
        }
        user.setPassword(new BCryptPasswordEncoder().encode(newPassword));
        userService.save(user);
        return new Resp("修改成功");
    }

    /**
     * @author zk
     * @date 2018-08-13 21:00
     * @Description 禁用用户
     */
    @PostMapping("/disable")
    @ApiOperation(value = "禁用用户")
    public Resp disable(String id) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp(Resp.PARAM_ERROR, "查无此用户");
        }
        if (user.getDelFlag().equals(CommonConstant.DEL_FLAG)) {
            return new Resp(Resp.PARAM_ERROR, "该用户已被禁用");
        }
        user.setDelFlag(CommonConstant.DEL_FLAG);
        userService.save(user);
        return new Resp("禁用成功");
    }

    /**
     * @author zk
     * @date 2018-08-13 21:00
     * @Description 启用用户
     */
    @PostMapping("/enable")
    @ApiOperation(value = "启用用户")
    public Resp enable(String id) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp(Resp.PARAM_ERROR, "查无此用户");
        }
        if (user.getDelFlag().equals(CommonConstant.NORMAL_FLAG)) {
            return new Resp(Resp.PARAM_ERROR, "该用户已启用");
        }
        user.setDelFlag(CommonConstant.NORMAL_FLAG);
        userService.save(user);
        return new Resp("启用成功");
    }

    @PostMapping("/reset_password")
    @ApiOperation(value = "重置密码")
    public Resp resetPassword(String id) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp(Resp.PARAM_ERROR, "查无此用户");
        }
        user.setPassword(new BCryptPasswordEncoder().encode("123456"));
        userService.save(user);
        return new Resp("密码已重置为：123456");
    }


}
